Go 的全局退出监听
经常会有全局监听退出信号的需求,例如编写的 HTTP 服务或者 gRPC 服务需要监听退出信号时就可以使用这个方式
// signal.go
package util
import (
"log"
"os"
"os/signal"
"syscall"
)
// RegisterExitHandlers is used to register exit handlers
func RegisterExitHandlers(cancelFunc func()) (stop chan struct{}) {
var exitSignals = []os.Signal{os.Interrupt, syscall.SIGTERM} // SIGTERM is POSIX specific
stop = make(chan struct{})
s := make(chan os.Signal, len(exitSignals))
signal.Notify(s, exitSignals...)
go func() {
// Wait for a signal from the OS before dispatching
// a stop signal to all other goroutines observing this channel.
<-s
log.Println("exit signal received")
if cancelFunc != nil {
cancelFunc()
}
close(stop)
}()
return stop
}
使用的时候也很简单
package main
import (
"context"
"log"
"stgo/util"
)
func main() {
log.Println("Starting...")
_, cancel := context.WithCancel(context.Background())
stop := util.RegisterExitHandlers(cancel)
defer cancel()
// here is something server.
<-stop
log.Panicln("Goodbye")
}
这样就能监听 ctrl + c 的退出信号了